$.fn.dataTableExt.oPagination.full_numbers = {
	/*
	 * Function: oPagination.full_numbers.fnInit
	 * Purpose:  Initialise dom elements required for pagination with a list of the pages
	 * Returns:  -
	 * Inputs:   object:oSettings - dataTables settings object
	 *           node:nPaging - the DIV which contains this pagination control
	 *           function:fnCallbackDraw - draw function which must be called on update
	 */
	"fnInit": function ( oSettings, nPaging, fnCallbackDraw )
	{
		var oLang = oSettings.oLanguage.oPaginate;
		var oClasses = oSettings.oClasses;
		var fnClickHandler = function ( e ) {
			if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) )
			{
				fnCallbackDraw( oSettings );
			}
		};
		
		$(nPaging).append(
			'<a  tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageFirst+'">'+oLang.sFirst+'</a>'+
			'<a  tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPagePrevious+'">'+oLang.sPrevious+'</a>'+
			'<span></span>'+
			'<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageNext+'">'+oLang.sNext+'</a>'+
			'<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageLast+'">'+oLang.sLast+'</a>'
		);
		var els = $('a', nPaging);
		var nFirst = els[0],
			nPrev = els[1],
			nNext = els[2],
			nLast = els[3];
	
		var nSkip = document.createElement( 'input' );
			nSkip.type = "text";
			nSkip.className = "input-inline";
			nSkip.style.width = "40px";
			nSkip.style.height = "18px";
			
		$(nPaging).append('<span class="paginate_skip_text">&nbsp;&nbsp;转到&nbsp;</span>');
		$(nPaging).append(nSkip);
		$(nPaging).append('<span class="paginate_skip_text" id="' + oSettings.sTableId + '_pagetotal"></span>');
		
		$(nSkip).keyup( function (e) {
			if ( e.which == 38 || e.which == 39 )
			{
				this.value++;
			}
			else if ( (e.which == 37 || e.which == 40) && this.value > 1 )
			{
				this.value--;
			}
			 
			if ( this.value == "" || this.value.match(/[^0-9]/) )
			{
				/* Nothing entered or non-numeric character */
				return;
			}
			
			if (this.value < 1)
			{
				this.value = 1;	
			}
			
			var iNewStart = oSettings._iDisplayLength * (this.value - 1);
				
			if ( iNewStart > oSettings.fnRecordsDisplay() )
			{
				/* Display overrun */
				oSettings._iDisplayStart = (Math.ceil((oSettings.fnRecordsDisplay()-1) / 
					oSettings._iDisplayLength)-1) * oSettings._iDisplayLength;
				fnCallbackDraw( oSettings );
				return;
			}
			 
			oSettings._iDisplayStart = iNewStart;
			fnCallbackDraw( oSettings );
		});
		
			
		oSettings.oApi._fnBindAction( nFirst, {action: "first"},    fnClickHandler );
		oSettings.oApi._fnBindAction( nPrev,  {action: "previous"}, fnClickHandler );
		oSettings.oApi._fnBindAction( nNext,  {action: "next"},     fnClickHandler );
		oSettings.oApi._fnBindAction( nLast,  {action: "last"},     fnClickHandler );
		
		/* ID the first elements only */
		if ( !oSettings.aanFeatures.p )
		{
			nPaging.id = oSettings.sTableId+'_paginate';
			nFirst.id =oSettings.sTableId+'_first';
			nPrev.id =oSettings.sTableId+'_previous';
			nNext.id =oSettings.sTableId+'_next';
			nLast.id =oSettings.sTableId+'_last';
		}
	},

	/*
	 * Function: oPagination.full_numbers.fnUpdate
	 * Purpose:  Update the list of page buttons shows
	 * Returns:  -
	 * Inputs:   object:oSettings - dataTables settings object
	 *           function:fnCallbackDraw - draw function to call on page change
	 */
	"fnUpdate": function ( oSettings, fnCallbackDraw )
	{
		if ( !oSettings.aanFeatures.p )
		{
			return;
		}

		var iPageCount = jQuery.fn.dataTableExt.oPagination.iFullNumbersShowPages;
		var iPageCountHalf = Math.floor(iPageCount / 2);
		var iPages = Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength);
		var iCurrentPage = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1;
		var sList = "";
		var iStartButton, iEndButton, i, iLen;
		var oClasses = oSettings.oClasses;
		var anButtons, anStatic, nPaginateList, nNode;
		var an = oSettings.aanFeatures.p;
		var fnBind = function (j) {
			oSettings.oApi._fnBindAction( this, {"page": j+iStartButton-1}, function(e) {
				/* Use the information in the element to jump to the required page */
				oSettings.oApi._fnPageChange( oSettings, e.data.page );
				fnCallbackDraw( oSettings );
				e.preventDefault();
			} );
		};
		
		/* Pages calculation */
		if ( oSettings._iDisplayLength === -1 )
		{
			iStartButton = 1;
			iEndButton = 1;
			iCurrentPage = 1;
		}
		else if (iPages < iPageCount)
		{
			iStartButton = 1;
			iEndButton = iPages;
		}
		else if (iCurrentPage <= iPageCountHalf)
		{
			iStartButton = 1;
			iEndButton = iPageCount;
		}
		else if (iCurrentPage >= (iPages - iPageCountHalf))
		{
			iStartButton = iPages - iPageCount + 1;
			iEndButton = iPages;
		}
		else
		{
			iStartButton = iCurrentPage - Math.ceil(iPageCount / 2) + 1;
			iEndButton = iStartButton + iPageCount - 1;
		}


		/* Build the dynamic list */
		for ( i=iStartButton ; i<=iEndButton ; i++ )
		{
			sList += (iCurrentPage !== i) ?
				'<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+'">'+i+'</a>' :
				'<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButtonActive+'">'+i+'</a>';
		}

		/* Loop over each instance of the pager */
		for ( i=0, iLen=an.length ; i<iLen ; i++ )
		{
			nNode = an[i];
			if ( !nNode.hasChildNodes() )
			{
				continue;
			}

			/* Build up the dynamic list first - html and listeners */
			$('span:eq(0)', nNode)
				.html( sList )
				.children('a').each( fnBind );
		
			$('#' + oSettings.sTableId + '_pagetotal').html('&nbsp;&nbsp;/&nbsp;&nbsp;' + iPages + '页');
			
			/* Update the permanent button's classes */
			anButtons = nNode.getElementsByTagName('a');
			anStatic = [
				anButtons[0], anButtons[1], 
				anButtons[anButtons.length-2], anButtons[anButtons.length-1]
			];

			$(anStatic).removeClass( oClasses.sPageButton+" "+oClasses.sPageButtonActive+" "+oClasses.sPageButtonStaticDisabled );
			$([anStatic[0], anStatic[1]]).addClass( 
				(iCurrentPage==1) ?
					oClasses.sPageButtonStaticDisabled :
					oClasses.sPageButton
			);
			$([anStatic[2], anStatic[3]]).addClass(
				(iPages===0 || iCurrentPage===iPages || oSettings._iDisplayLength===-1) ?
					oClasses.sPageButtonStaticDisabled :
					oClasses.sPageButton
			);
		}
	}
}